<template>
  <div class="content">
    <el-upload
      ref="fileUpload"
      :action="uploadUrl"
      :accept="accept"
      :before-upload="beforeUpload"
      :on-change="handleChange"
      :before-remove="beforeRemove"
      :on-remove="handleRemove"
      :on-success="handleSuccess"
      :on-exceed="handleExceed"
      :drag="listType !== 'picture-card'"
      :multiple="limit > 1"
      :limit="limit === 1 ? 2 : limit"
      :file-list="fileList"
      :list-type="listType"
      :headers="header"
    >
      <el-icon v-if="listType === 'picture-card'" class="avatar-uploader-icon">
        <Plus />
      </el-icon>

      <el-icon v-if="listType !== 'picture-card'">
        <Upload />
      </el-icon>
      <div v-if="listType !== 'picture-card'" class="el-upload__text">
        将文件拖到此处，或
        <em>点击上传</em>
      </div>
      <template #tip>
        <div v-if="tips" class="el-upload__tip">{{ tips }}</div>
      </template>
    </el-upload>
  </div>
</template>

<script lang="ts" setup>
  import { ref, reactive, watch, onMounted, computed } from 'vue'
  import { Plus, Upload } from '@element-plus/icons-vue'
  import { ElMessage, ElMessageBox } from 'element-plus'
  import type { UploadFile, UploadRawFile } from 'element-plus'

  // 这些工具函数暂时注释掉，等外部实现后再启用
  // import { getToken } from '@/utils/auth'
  // import { compressImage } from '@/utils/upload'

  // 临时模拟函数，实际使用时请替换为真实的导入
  const getToken = () => 'mock-token'
  const compressImage = (file: any, compress: number) => file

  // 定义 props 类型
  interface Props {
    modelValue?: UploadFile[]
    accept?: string
    tips?: string
    listType?: 'text' | 'picture' | 'picture-card'
    limit?: number
    compress?: number
  }

  // 定义 emits 类型
  interface Emits {
    (e: 'update:modelValue', value: UploadFile[]): void
    (e: 'select', file: UploadRawFile | UploadFile): void
  }

  // Props 定义
  const props = withDefaults(defineProps<Props>(), {
    modelValue: () => [],
    accept: undefined,
    tips: undefined,
    listType: 'text',
    limit: 1,
    compress: 0,
  })

  // Emits 定义
  const emit = defineEmits<Emits>()

  // 响应式数据
  const fileUpload = ref()
  const fileList = ref<UploadFile[]>([])

  // 计算属性
  const uploadUrl = computed(() => {
    return import.meta.env.VITE_APP_BASE_API + '/api/common/file/upload'
  })

  const header = reactive<Record<string, string>>({})

  // 监听 modelValue 变化
  watch(
    () => props.modelValue,
    (val) => {
      fileList.value = val || []
    },
    { immediate: true },
  )

  // 填充数据
  const fillValue = () => {
    fileList.value = props.modelValue || []
  }

  // 文件超出个数限制时的钩子
  const handleExceed = () => {
    ElMessage.warning(`每次只能上传 ${props.limit} 个文件`)
  }

  // 删除文件之前的钩子
  const beforeRemove = async () => {
    try {
      await ElMessageBox.confirm('确定移除文件吗？')
      return true
    } catch {
      return false
    }
  }

  // 文件列表移除文件时的钩子
  const handleRemove = (file: UploadFile) => {
    // 移除文件
    const index = fileList.value.findIndex((item) => item.uid === file.uid)
    if (index > -1) {
      fileList.value.splice(index, 1)
    }
    emit('update:modelValue', fileList.value)
  }

  // 文件上传成功时的钩子
  const handleSuccess = (res: any, file: UploadFile, list: UploadFile[]) => {
    if (res.code !== 0) {
      ElMessage.error(res.msg)
      emit('update:modelValue', [])
      return
    }

    let updatedList = [...list]

    // 只能传一个的进行替换
    if (props.limit === 1 && updatedList.length > 1) {
      const url = res.data.url
      updatedList = [
        {
          name: url,
          url: url,
          uid: file.uid!,
          status: 'success',
        },
      ]
    } else {
      // 上传成功替换服务端URL
      for (let i = 0; i < updatedList.length; i++) {
        if (file.uid === updatedList[i].uid) {
          updatedList[i].url = res.data.url
        }
      }
    }

    emit('update:modelValue', updatedList)
  }

  // 文件变化重新上传
  const handleChange = (file: UploadFile, list: UploadFile[]) => {
    if (props.limit === 1 && list.length > 1) {
      list.splice(0, 1)
    }
  }

  // 文件上传前的校验
  const beforeUpload = (file: UploadRawFile) => {
    console.log('++++++++++文件名称：', file.name)
    emit('select', file)
    // 压缩上传
    return compressImage(file, props.compress)
  }

  // 生命周期
  onMounted(() => {
    fillValue()
    header.token = getToken()
  })
</script>

<style scoped>
  :deep(.el-list-enter-active),
  :deep(.el-list-leave-active) {
    transition: none;
  }
</style>
